package com.lyshop.jinding.utils;

import android.annotation.SuppressLint;
import android.app.Dialog;
import android.app.DownloadManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.os.Process;
import android.provider.Settings;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.core.content.FileProvider;

import com.hjq.permissions.OnPermissionCallback;
import com.hjq.permissions.Permission;
import com.hjq.permissions.XXPermissions;
import com.lyshop.jinding.R;
import com.zc.mychart.utils.ArithUtil;

import java.io.File;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * Created by 14658 on 2016/7/4.
 */
public class UpdateVersionUtil {

    private Context mContext;
    private DownloadManager mDownloadManager;
    private Dialog dialog;
    private long downloadId;
    private String apkUrl;//下载路径
    private String content;//下载说明
    private String code;//版本号
    private boolean isForcedToUpdate;
    public static boolean isUpdating;//更新中
    private static boolean isUpdateCancel;//稍后更新
    private static long lastCancelTime;
    private final static long TIME_INTERVAL = 60 * 60 * 1000;//忽略更新提醒时间为1小时
    private String fileName;
    public static final int HANDLE_DOWNLOAD = 0x001;

    private static final int mUnit = 1024 * 1024;

    private LinearLayout ll_upgrade_progress;
    private LinearLayout ll_upgrade_btn;

    private ProgressBar pb_experience;
    private TextView tv_progress;
    private int ALL_PERMISSION = 1000;


    public UpdateVersionUtil(Context context, String code, String apkUrl, String content, String upgradeType) {
        this.mContext = context;
        this.code = code;
        this.apkUrl = apkUrl;
        this.content = content.replaceAll("\\\\r\\\\n", "\r\n");
        this.isForcedToUpdate = "1".equals(upgradeType);
        this.fileName = "yidian" + code.replaceAll("\\.", "") + ".apk";
    }

    public UpdateVersionUtil(Context context, String apkUrl) {
        this.mContext = context;
        this.apkUrl = apkUrl;
        this.fileName = "yidian" + System.currentTimeMillis() + ".apk";
    }

    //外部接口让主Activity调用
    public void checkUpdateInfo() {
        showUpgradeDialog();
    }

    public static boolean isUpdateCancel() {
        if (System.currentTimeMillis() - lastCancelTime > TIME_INTERVAL) {
            return false;
        } else {
            return isUpdateCancel;
        }
    }

    private void showUpgradeDialog() {
        dialog = new Dialog(mContext, R.style.dialog);
        View view = LayoutInflater.from(mContext).inflate(R.layout.dialog_update, null);
        dialog.setContentView(view);
        dialog.setCanceledOnTouchOutside(false);
        dialog.setCancelable(false);
        Window window = dialog.getWindow();
        window.setGravity(Gravity.CENTER);
        TextView tv_version = view.findViewById(R.id.tv_version);
        TextView tv_content = view.findViewById(R.id.tv_content);
        TextView tv_cancel = view.findViewById(R.id.tv_cancel);
        Button bt_upgrade = view.findViewById(R.id.bt_upgrade);
        Button bt_go_browser = view.findViewById(R.id.bt_go_browser);

        ll_upgrade_progress = view.findViewById(R.id.ll_upgrade_progress);
        ll_upgrade_btn = view.findViewById(R.id.ll_upgrade_btn);
        pb_experience = view.findViewById(R.id.pb_experience);
        tv_progress = view.findViewById(R.id.tv_progress);

        tv_version.setText("v" + code);
        if (content != null && !content.equals("")) {
            tv_content.setText(content);
        }
        tv_cancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                dialog.dismiss();
                lastCancelTime = System.currentTimeMillis();
                isUpdating = false;
                isUpdateCancel = true;
            }
        });
        bt_upgrade.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
//                if (!isForcedToUpdate) {
//                    dialog.dismiss();
//                }
                showDownloadDialog();
            }
        });

        bt_go_browser.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!apkUrl.contains("http")) return;
                Uri uri = Uri.parse(apkUrl);
                Intent intent = new Intent(Intent.ACTION_VIEW, uri);
                mContext.startActivity(intent);
            }
        });

        if (isForcedToUpdate) {
            tv_cancel.setVisibility(View.GONE);
        } else {
            tv_cancel.setVisibility(View.VISIBLE);
        }
        dialog.setOnShowListener(new DialogInterface.OnShowListener() {
            @Override
            public void onShow(DialogInterface dialog) {
                if (null != listener) {
                    listener.onShow();
                }

            }
        });
        dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
            @Override
            public void onDismiss(DialogInterface dialog) {
                if (null != listener) {
                    listener.onDismiss();
                    unregisterContentObserver();
                }
            }
        });
        isUpdating = true;
        if (!dialog.isShowing()) {
            dialog.show();
        }
    }

    public boolean isShown() {
        if (null != dialog) {
            return dialog.isShowing();
        } else {
            return false;
        }
    }

    /**
     * 通知栏显示下载进度
     */
    public void showDownloadDialog() {
// 跳转至设置页面，让用户手动开启
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            if (!Environment.isExternalStorageManager()) {
                Intent intent = new Intent(
                        Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
                intent.setData(Uri.parse("package:" + mContext.getPackageName()));
                mContext.startActivity(intent);
            } else {
                downloadApk();
            }
        } else {
            XXPermissions.with(mContext)
                    .permission(Permission.WRITE_EXTERNAL_STORAGE)
                    .request(new OnPermissionCallback() {
                        @Override
                        public void onGranted(@NonNull List<String> permissions, boolean allGranted) {
                            downloadApk();
                        }

                        @Override
                        public void onDenied(@NonNull List<String> permissions, boolean doNotAskAgain) {
                            if (doNotAskAgain) {
                                ToastUtil.showToast(mContext, "被永久拒绝授权，请手动授予录音和日历权限");
                                // 如果是被永久拒绝就跳转到应用权限系统设置页面
                                XXPermissions.startPermissionActivity(mContext, permissions);
                            } else {
                                ToastUtil.showToast(mContext, "存储权限已关闭");
                            }
                        }
                    });
        }
    }


    private void downloadApk() {
        try {
//            if (!isForcedToUpdate) {
//                dialog.dismiss();
//            }
            File apkFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), fileName);
            if (apkFile.exists()) {
                apkFile.delete();
            }

            //使用系统下载类
            mDownloadManager = (DownloadManager) mContext.getSystemService(Context.DOWNLOAD_SERVICE);
            downloadObserver = new DownloadChangeObserver();
            registerContentObserver();

            Uri uri = Uri.parse(apkUrl);
            DownloadManager.Request request = new DownloadManager.Request(uri);
            request.setAllowedOverRoaming(false);
            //创建目录下载
            request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName);
            // 把id保存好，在接收者里面要用
            downloadId = mDownloadManager.enqueue(request);
            //设置允许使用的网络类型，这里是移动网络和wifi都可以
            request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE | DownloadManager.Request.NETWORK_WIFI);
            //机型适配
            request.setMimeType("application/vnd.android.package-archive");
            //通知栏显示
            request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
            request.setTitle("版本更新...");
            request.setDescription("正在下载中...");
            request.setVisibleInDownloadsUi(true);
            mContext.registerReceiver(mReceiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
            ToastUtil.showToast(mContext, "正在下载,下载进度请查看通知栏");
        } catch (Exception e) {
            ToastUtil.showToast(mContext, "下载出错..请重试");
            e.printStackTrace();
        }

    }

    private void killApp() {
        if (isForcedToUpdate) {
            //MobclickAgent.onKillProcess(mContext);
            Process.killProcess(Process.myPid());
        } else {
            lastCancelTime = System.currentTimeMillis();
            isUpdating = false;
            isUpdateCancel = true;
        }
    }

    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            checkStatus();
        }
    };

    /**
     * 检查下载状态
     */
    private void checkStatus() {
        DownloadManager.Query query = new DownloadManager.Query();
        query.setFilterById(downloadId);
        Cursor cursor = mDownloadManager.query(query);
        if (cursor.moveToFirst()) {
            @SuppressLint("Range") int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
            switch (status) {
                //下载暂停
                case DownloadManager.STATUS_PAUSED:
                    break;
                //下载延迟
                case DownloadManager.STATUS_PENDING:
                    break;
                //正在下载
                case DownloadManager.STATUS_RUNNING:
                    int curren = cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
                    int max = cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
                    Log.e("art", curren + "/" + max);
                    break;
                //下载完成
                case DownloadManager.STATUS_SUCCESSFUL:
                    installAPK();
                    isUpdating = false;
                    unregisterContentObserver();
                    break;
                //下载失败
                case DownloadManager.STATUS_FAILED:
                    ToastUtil.showToast(mContext, "下载失败");
                    unregisterContentObserver();
                    resetBtn();
                    if (isForcedToUpdate) {
                        checkUpdateInfo();
                    } else {
                        lastCancelTime = System.currentTimeMillis();
                        isUpdating = false;
                        isUpdateCancel = true;
                    }
                    break;
            }
        }
        cursor.close();
    }

    private void installAPK() {
        try {
            File apkFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), fileName);

            XXPermissions.with(mContext)
                    .permission(Permission.REQUEST_INSTALL_PACKAGES)
                    .request(new OnPermissionCallback() {

                        @Override
                        public void onGranted(List<String> permissions, boolean all) {
                            if (!all) {
                                return;
                            }

                            Intent intent = new Intent(Intent.ACTION_VIEW);
                            // 判断版本大于等于7.0
                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                                // 设置 FLAG_GRANT_READ_URI_PERMISSION 以允许读取 Uri 指定的数据
                                intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                                // 通过 FileProvider 创建一个 content 类型的 Uri
                                Uri contentUri = FileProvider.getUriForFile(mContext, "com.yx.snshop.fileprovider", apkFile);
                                intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
                            } else {
                                intent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");
                            }
                            mContext.startActivity(intent);
                        }
                    });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    private DownloadChangeObserver downloadObserver;
    private ScheduledExecutorService scheduledExecutorService;

    /**
     * 注册ContentObserver
     */
    private void registerContentObserver() {
        /** observer download change **/
        if (downloadObserver != null) {
            mContext.getContentResolver().registerContentObserver(
                    Uri.parse("content://downloads/my_downloads"), false, downloadObserver);
        }
    }

    /**
     * 注销ContentObserver
     */
    private void unregisterContentObserver() {
        if (downloadObserver != null) {
            mContext.getContentResolver().unregisterContentObserver(downloadObserver);
        }
    }

    /**
     * 监听下载进度
     */
    private class DownloadChangeObserver extends ContentObserver {

        public DownloadChangeObserver() {
            super(downLoadHandler);
            scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
        }

        /**
         * 当所监听的Uri发生改变时，就会回调此方法
         *
         * @param selfChange 此值意义不大, 一般情况下该回调值false
         */
        @Override
        public void onChange(boolean selfChange) {
            scheduledExecutorService.scheduleAtFixedRate(progressRunnable, 0, 1, TimeUnit.SECONDS); //在子线程中查询
        }
    }

    @SuppressLint("HandlerLeak")
    public Handler downLoadHandler = new Handler() { //主线程的handler
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (HANDLE_DOWNLOAD == msg.what) {
                //被除数可以为0，除数必须大于0
//                if (msg.arg1 >= 0 && msg.arg2 > 0) {
//                    Log.e("art", +"/" + msg.arg2 + "");
//                }

                if (null != ll_upgrade_progress) {
                    ll_upgrade_progress.setVisibility(View.VISIBLE);
                    ll_upgrade_btn.setVisibility(View.GONE);
                    pb_experience.setMax(msg.arg2);
                    pb_experience.setProgress(msg.arg1);
                    String duration = ArithUtil.format(ArithUtil.div(msg.arg1, mUnit)) + "m/" + ArithUtil.format(ArithUtil.div(msg.arg2, mUnit)) + "m";
                    tv_progress.setText(duration);
                }
            }
        }
    };

    private void resetBtn() {
//        ll_upgrade_progress.setVisibility(View.VISIBLE);
        ll_upgrade_progress.setVisibility(View.GONE);
        ll_upgrade_btn.setVisibility(View.VISIBLE);
    }

    private Runnable progressRunnable = new Runnable() {
        @Override
        public void run() {
            updateProgress();
        }
    };

    private void updateProgress() {
        int[] bytesAndStatus = getBytesAndStatus(downloadId);
        downLoadHandler.sendMessage(downLoadHandler.obtainMessage(HANDLE_DOWNLOAD, bytesAndStatus[0], bytesAndStatus[1], bytesAndStatus[2]));
    }

    private int[] getBytesAndStatus(long downloadId) {
        int[] bytesAndStatus = new int[]{
                0, 0, 0
        };
        DownloadManager.Query query = new DownloadManager.Query().setFilterById(downloadId);
        Cursor cursor = null;
        try {
            cursor = mDownloadManager.query(query);
            if (cursor != null && cursor.moveToFirst()) {
                //已经下载文件大小
                bytesAndStatus[0] = cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
                //下载文件的总大小
                bytesAndStatus[1] = cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
                //下载状态
                bytesAndStatus[2] = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
            }
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
        return bytesAndStatus;
    }


    private UpgradeDialogListener listener;

    public void setListener(UpgradeDialogListener listener) {
        this.listener = listener;
    }

    public interface UpgradeDialogListener {

        void onShow();

        void onDismiss();
    }
}
